#include <cinttypes>
#include <cstddef>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <string>
#include <time.h>
#include "../common.h"
extern "C" {
#include "../yy.h"
}
#include "../sizer.h"
#include "../pcoder.h"
#include "../display.h"
#include "pic16e.h"
#include "pic16e_asm.h"
#include "pic16e_inst.h"

// 2 -> 1
void PIC16E :: parseMovItem(Item *ip, int idx, int offset){
	char buf[64];
	switch (ip->type) {
		case ID_ITEM: {
			if (ip->attr->isStatic == -1){
				char buf[64];
				if (idx == 2){
						sprintf(buf,"\tlui \ta6,%%hi(%s)\n\tlw  \ta5,%%lo(%s)(a6)\n", ip->vname, ip->vname); 
						ASM_OUTP(buf);
				}	
				else if (idx == 1){
					sprintf(buf,"\tlui \ta6,%%hi(%s)\n\tsw  \ta5,%%lo(%s)(a6)\n", ip->vname, ip->vname); 
					ASM_OUTP(buf);
				}
				break;
			}
			Dnode* dp = serachVarable(ip->vname);
			if (idx == 1){
				if (dp->attr->dimVect){
					char buf[128];
					int _offset = std::atoi(dp->memStr) + offset;
					sprintf(buf,"\tsw  \ta5, %d(s0)\n",_offset); ASM_OUTP(buf);
				}else {
					ASM_CODE(_SW,_R_A5,dp->memStr);
				}
			} else if (idx == 2){
				ASM_CODE(_LW,_R_A5,dp->memStr);
			}
		}break;
		case IMMD_ITEM: {
			errPrint("immd_item can not be appear at immd_item");
		}break;
		case CON_ITEM: {
			ASM_CODE(_LI,_R_A5,ip->val.i);
		}break;
		case INDIR_ITEM:{
			char buf[64]; sprintf(buf,"\tmv  \ta4, t%d\n", ip->memRgx); ASM_OUTP(buf);
			if (curFunc != NULL){
				if (ip->fname != curFunc->name){
					errPrint("function not matched error");
				}
				Dnode* dp = serachVarable(ip->vname);	
				char buf[128];
				if (idx == 2){
					if (dp->attr->dimVect){
						char buf[128];
						int _offset = std::atoi(dp->memStr) + offset;
						sprintf(buf,"\tlw  \ta4, %d(s0)\n",_offset); ASM_OUTP(buf);
					}else {
						
					}
				}
			}
		}break;
		case ACC_ITEM:{
			if (idx == 1){
				ASM_CODE(_MV,_R_A0,_R_A5);
			}
			else if(idx == 2){
				ASM_CODE(_MV,_R_A5,_R_A0);
			}
		}
	    break;
		case TEMP_ITEM:{
			if (idx == 2){
					char buf[64]; sprintf(buf,"\tmv  \ta5, t%d\n", ip->memRgx); ASM_OUTP(buf);
			}else if (idx == 1){
					char buf[64]; sprintf(buf,"\tmv  \tt%d, a5\n", ip->memRgx); ASM_OUTP(buf);
			}
		}
		default:{}
	}
}

void PIC16E :: mov(Item *ip0, Item *ip1)
{
	parseMovItem(ip1, 2, ip1->attr->offset);
	parseMovItem(ip0, 1, ip1->attr->offset);
}

// pcode "=" a 1
// lw  1